﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;
using SFP;

namespace LevelEditor
{
    public partial class ObjectPreferencesForm : Form
    {
        private LevelEditorForm levelEditorForm;
        private ObjectLE objectLE;
        private Bitmap objectImg;
        private string relativeImgFilePath;

        public ObjectPreferencesForm(ObjectLE objectLE, LevelEditorForm levelEditorForm)
        {
            InitializeComponent();

            this.levelEditorForm = levelEditorForm;
            this.objectLE = objectLE;
            objectIDLabel.Text = "" + objectLE.id;
            nameTextBox.Text = objectLE.Name;
            typeTextBox.Text = objectLE.Type;
            relativeImgFilePath = objectLE.ObjectImgPath;
            if (relativeImgFilePath != null && !"".Equals(relativeImgFilePath))
                imageFileLabel.Text = objectLE.ObjectImgFileName;
            objectImg = objectLE.ObjectImg;
            if (objectImg != null)
            {
                objectPictureBox.Image = prepareImageForPreview(objectImg);
            }

            levelEditorForm.SetDialogFormOpen(true);
        }

        private void loadButton_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Title = "Load an image";
            openFileDialog.InitialDirectory = Application.StartupPath;
            openFileDialog.Multiselect = false;
            openFileDialog.Filter = "Bilddaten|*.png;*.jpg;*.jpeg;*.gif";

            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                string absolutePath = openFileDialog.FileName;
                string relativePath = absolutePath.Replace(Application.StartupPath + "\\", "");

                if (openFileDialog.FileName.Equals(Application.StartupPath + "\\" + relativePath))
                {
                    relativeImgFilePath = relativePath;
                    imageFileLabel.Text = Path.GetFileName(openFileDialog.FileName); ;

                    Bitmap orgBitmap = new Bitmap(absolutePath);
                    orgBitmap.SetResolution(96.0f, 96.0f);

                    objectImg = new Bitmap(orgBitmap.Width, orgBitmap.Height, PixelFormat.Format32bppPArgb);
                    Graphics.FromImage(objectImg).DrawImage(orgBitmap, 0, 0);

                    objectPictureBox.Image = prepareImageForPreview(new Bitmap(objectImg));
                    
                    Refresh();
                }
                else
                {
                    SendKeys.Send("%");
                    MessageBox.Show("The image file needs to be copied into the application's startup directory or one of its subdirectories!", "Warning!", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
            }
        }

        private Bitmap prepareImageForPreview(Bitmap preparedImage)
        {
            float resizeFactor = 1;

            float widthDiff = preparedImage.Width - objectPictureBox.Width;
            float heightDiff = preparedImage.Height - objectPictureBox.Height;
            float newWidth = preparedImage.Width;
            float newHeight = preparedImage.Height;
            if (widthDiff > heightDiff)
            {
                if (widthDiff > 0)
                {
                    newWidth = objectPictureBox.Width;
                    newHeight = preparedImage.Height * ((float)objectPictureBox.Width / (float)preparedImage.Width);
                    resizeFactor = (float)objectPictureBox.Width / (float)preparedImage.Width;
                }
            }
            else
            {
                if (heightDiff > 0)
                {
                    newHeight = objectPictureBox.Height;
                    newWidth = preparedImage.Width * ((float)objectPictureBox.Height / (float)preparedImage.Height);
                    resizeFactor = (float)objectPictureBox.Height / (float)preparedImage.Height;
                }
            }

            Bitmap preparedImageForPreview = new Bitmap(preparedImage, (int)newWidth, (int)newHeight);
            drawImageRaster(Graphics.FromImage(preparedImageForPreview), preparedImageForPreview.Size, resizeFactor);
            return preparedImageForPreview;
        }

        private void drawImageRaster(Graphics g, Size size, float resizeFactor)
        {
            float rasterSize = levelEditorForm.GetRasterSize();
            rasterSize *= resizeFactor;
            Pen rasterPen = levelEditorForm.GetRasterPen();

            for (float i = 0; i <= size.Width; i += rasterSize)
            {
                g.DrawLine(rasterPen, new PointF(i, 0), new PointF(i, size.Height));
            }

            for (float i = size.Height - 1; i >= 0; i -= rasterSize)
            {
                g.DrawLine(rasterPen, new PointF(0, i), new PointF(size.Width, i));
            }
        }

        private void clearButton_Click(object sender, EventArgs e)
        {
            objectPictureBox.Image = null;
            objectImg = null;
            relativeImgFilePath = "";
            imageFileLabel.Text = "No image loaded...";
        }

        private void applyButton_Click(object sender, EventArgs e)
        {
            objectLE.Name = nameTextBox.Text;
            objectLE.Type = typeTextBox.Text;
            objectLE.GetObjectPictureBox().Image = objectImg;
            objectLE.ObjectImg = objectImg;
            objectLE.ObjectImgPath = relativeImgFilePath;
            objectLE.ObjectImgFileName = imageFileLabel.Text;

            foreach (GameObject gameObject in objectLE.GetLinkedGameObjects().Keys)
            {
                gameObject.Name = objectLE.Name;
                gameObject.Type = objectLE.Type;
                gameObject.Image = objectLE.ObjectImg;
            }

            Close();
        }

        private void cancelButton_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void ObjectPreferencesForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            levelEditorForm.SetDialogFormOpen(false);
        }
    }
}
